﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Acme.BookStore.Permissions;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Features;

namespace Acme.BookStore.Authors
{
    [RequiresFeature("BookStore.Author")]
    public class AuthorAppService : BookStoreAppService, IAuthorAppService
    {
        IAuthorRepository authorRepository;
        AuthorManager authorManager;
        ILocalEventBus localEventBus;

        public AuthorAppService(IAuthorRepository authorRepository,AuthorManager authorManager, ILocalEventBus localEventBus)
        {
            this.authorRepository = authorRepository;
            this.authorManager = authorManager;
            this.localEventBus = localEventBus;
        }

        [Authorize(BookStorePermissions.Authors.Create)]
        public async Task<AuthorDto> CreateAsync(CreateAuthorDto input)
        {
            var author = await authorManager.CreateAsync(input.Name, input.BirthDate, input.ShortBio);
            await authorRepository.InsertAsync(author);
            await localEventBus.PublishAsync<AuthorCreatedEvent>(new AuthorCreatedEvent()
            {
                Author = author
            });
            return ObjectMapper.Map<Author, AuthorDto>(author);
        }

        [Authorize(BookStorePermissions.Authors.Delete)]
        public async Task DeleteAsync(Guid id)
        {
            await authorRepository.DeleteAsync(id);
        }

        [Authorize(BookStorePermissions.Authors.Default)]
        public async Task<AuthorDto> GetAsync(Guid id)
        {
            var authorEntity = await authorRepository.GetAsync(id);
            return ObjectMapper.Map<Author, AuthorDto>(authorEntity);
        }

        [Authorize(BookStorePermissions.Authors.Default)]
        public async Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input)
        {
            if (input.Sorting.IsNullOrWhiteSpace()) input.Sorting = nameof(Author.Name);
            var authors = await authorRepository.GetListAsync(input.SkipCount, input.MaxResultCount, input.Sorting, input.Filter, true);
            var ret = new PagedResultDto<AuthorDto>(
                authors.totalCount.Value,
                ObjectMapper.Map<List<Author>, List<AuthorDto>>(authors.authors)
            );
            return ret;
        }

        [Authorize(BookStorePermissions.Authors.Edit)]
        public async Task UpdateAsync(Guid id, UpdateAuthorDto input)
        {
            var author = await authorRepository.GetAsync(id);

            await authorManager.ChangeNameAsync(author, input.Name);
            author.BirthDate = input.BirthDate;
            author.ShortBio=input.ShortBio;

            await authorRepository.UpdateAsync(author);
        }
    }
}
